package org.cybzacg.convert.converters.gather;

import org.cybzacg.convert.annotation.Converter;
import org.cybzacg.convert.enums.ConversionError;
import org.cybzacg.convert.enums.ConversionPriority;
import org.cybzacg.convert.enums.ConversionType;
import org.cybzacg.convert.exception.ConversionException;
import lombok.extern.slf4j.Slf4j;

import java.util.*;
import java.util.concurrent.*;

/**
 * Queue类型转换器
 * 支持各种Queue类型之间的转换
 *
 * @author cybzacg.blog
 * @version 4.0
 * @since 3.0
 */
@Slf4j
@Converter(name = "QueueConverter", priority = ConversionPriority.MEDIUM, description = "Queue类型转换器，支持各种Queue类型之间的转换", enabled = true, version = "4.0", author = "cybzacg.blog", supportedTypes = {
        Queue.class }, tags = { "queue", "collection", "conversion" })
public class QueueConverter extends AbstractCollectionConverter<Queue<Object>> {

    // Queue类型实现类映射
    private static final Map<Class<?>, Class<?>> QUEUE_IMPLEMENTATIONS = new HashMap<>();

    static {
        QUEUE_IMPLEMENTATIONS.put(Queue.class, LinkedList.class);
        QUEUE_IMPLEMENTATIONS.put(AbstractQueue.class, LinkedList.class);
        QUEUE_IMPLEMENTATIONS.put(BlockingQueue.class, LinkedBlockingQueue.class);
    }

    public QueueConverter() {
        super(Queue.class, ConversionPriority.MEDIUM);
    }

    @Override
    protected ConversionType getConversionType() {
        return ConversionType.QUEUE;
    }

    @Override
    @SuppressWarnings("unchecked")
    protected <T> Queue<Object> createEmptyCollection(Class<T> targetType) {
        try {
            // 如果是具体的Queue实现类，直接实例化
            if (Queue.class.isAssignableFrom(targetType) &&
                    !targetType.isInterface() &&
                    !java.lang.reflect.Modifier.isAbstract(targetType.getModifiers())) {
                return (Queue<Object>) targetType.getDeclaredConstructor().newInstance();
            }

            // 根据接口类型选择实现类
            Class<?> implementationClass = QUEUE_IMPLEMENTATIONS.get(targetType);
            if (implementationClass != null) {
                return (Queue<Object>) implementationClass.getDeclaredConstructor().newInstance();
            }

            // 根据目标类型特征选择合适的实现
            if (targetType.getName().contains("PriorityQueue")) {
                return new PriorityQueue<>();
            } else if (targetType.getName().contains("LinkedBlockingQueue") ||
                    targetType.getName().contains("BlockingQueue")) {
                return new LinkedBlockingQueue<>();
            } else if (targetType.getName().contains("ConcurrentLinkedQueue")) {
                return new ConcurrentLinkedQueue<>();
            } else if (targetType.getName().contains("ArrayBlockingQueue")) {
                return new ArrayBlockingQueue<>(100); // 默认容量100
            }

            // 默认使用LinkedList（实现了Queue接口）
            return new LinkedList<>();

        } catch (Exception e) {
            throw new ConversionException(ConversionError.CONVERSION_FAILED,
                    "无法创建Queue实例: " + targetType.getSimpleName(), e);
        }
    }

    @Override
    protected String getDefaultMapConversionMode() {
        return "values"; // Queue默认转换Map的values（FIFO顺序）
    }

    @Override
    public String getName() {
        return "QueueConverter";
    }

    // ========== 静态工具方法 ==========

    /**
     * 检查是否为Queue类型
     */
    public static boolean isQueueType(Class<?> clazz) {
        return Queue.class.isAssignableFrom(clazz);
    }

    /**
     * 创建LinkedList Queue的便捷方法
     */
    public static LinkedList<Object> toQueue(Object source) {
        QueueConverter converter = new QueueConverter();
        try {
            return (LinkedList<Object>) converter.convertToCollection(source, LinkedList.class, null);
        } catch (Exception e) {
            throw new ConversionException(ConversionError.CONVERSION_FAILED,
                    "转换为Queue失败: " + source, e);
        }
    }

    /**
     * 创建PriorityQueue的便捷方法
     */
    public static PriorityQueue<Object> toPriorityQueue(Object source) {
        QueueConverter converter = new QueueConverter();
        try {
            return (PriorityQueue<Object>) converter.convertToCollection(source, PriorityQueue.class, null);
        } catch (Exception e) {
            throw new ConversionException(ConversionError.CONVERSION_FAILED,
                    "转换为PriorityQueue失败: " + source, e);
        }
    }

    /**
     * 检查Queue是否为空或null
     */
    public static boolean isEmpty(Queue<?> queue) {
        return queue == null || queue.isEmpty();
    }

    /**
     * 获取Queue的安全大小
     */
    public static int safeSize(Queue<?> queue) {
        return queue != null ? queue.size() : 0;
    }
}
